package com.igd.business.dao.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.igd.business.dao.IBaseDao;
import com.igd.common.client.IbatisCallBack;
import com.igd.common.client.IbatisSqlExecutor;
import com.igd.exceptions.IgdException;
import com.igd.pojo.po.TblIgdDictionary;
import com.igd.pojo.vo.PageList;

/**
 * createDate:2013-6-16
 *
 * author:QIAOYU
 *
 * version:1.0
 *
 * description:公用DAO方法接口实现类
 */

@SuppressWarnings("deprecation")
public class IBaseDaoImpl extends SqlMapClientDaoSupport implements IBaseDao {
	
	private final String EMPTY_STATMENT_OR_PARAM = "err.sql.EmptyStatmentOrParam";
	
	/** 获取系统字典数据SQL */
	private final String GET_DIC_SQL = "dic.getDic";
	
	public boolean batchExecute(String sqlName, final List<?> list,final IbatisCallBack callBack) throws IgdException {

		if(StringUtils.isNotEmpty(sqlName) && null != list && list.size() > 0){
			
			return (Boolean) this.getSqlMapClientTemplate().execute(new SqlMapClientCallback<Object>() {

				public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
					
					return callBack.execute(new IbatisSqlExecutor(executor));
					
				}
			});
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);
			
		}
	}

	public String generatePrimaryKey(String sqlName) throws SQLException, IgdException {
		
		TblIgdDictionary dic = new TblIgdDictionary();
		
		dic.setDicKey("0000");
		
		dic.setDicSubKey("0000");
		
		TblIgdDictionary dbProductNameDic = this.queryForObject(GET_DIC_SQL, dic);
		
		if(null != dbProductNameDic && StringUtils.isNotEmpty(dbProductNameDic.getDicValue())){
			
			if(dbProductNameDic.getDicValue().toLowerCase().equals("oracle")){
				
				return this.queryForObject(sqlName, new String());
				
			}else{
				
				String dbCurrentKey = this.queryForObject(sqlName, new String());
				
				if(StringUtils.isNotEmpty(dbCurrentKey)){
					
					if(StringUtils.isNumeric(dbCurrentKey)){
						
						int key = Integer.parseInt(dbCurrentKey) + 1;
						
						return String.valueOf(key);
					}
					
				}else{
					
					return "1";

				}
			}
		}
		
		return null;
	}
	
	public void delete(String sqlName, Object param) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			this.getSqlMapClient().delete(sqlName,param);

		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}
	
	public void save(String sqlName, Object param) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			this.getSqlMapClient().insert(sqlName, param);
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}

	public void update(String sqlName, Object param) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			this.getSqlMapClient().insert(sqlName, param);
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}

	public <T> T queryForObject(String sqlName, T param) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			return this.queryForObject(sqlName, param, param);
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);
			
		}
	}

	public <T> List<T> queryForList(String sqlName, T param) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			List<?> list = this.getSqlMapClient().queryForList(sqlName, param);
			
			List<T> returnList = null;
			
			if(null != list && list.size() > 0){
				
				returnList = new ArrayList<T>(list.size());
				
				for(Object o:list){
					
					T t = (T)o;
					
					returnList.add(t);

				}
				
				list.clear();

			}
			
			return returnList;
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}
	
	public <T> List<T> queryForList(String sqlName,Object param,T resultTye) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			List<?> list = this.getSqlMapClient().queryForList(sqlName, param);
			
			List<T> returnList = null;
			
			if(null != list && list.size() > 0){
				
				returnList = new ArrayList<T>(list.size());
				
				for(Object o:list){
					
					T t = (T)o;
					
					returnList.add(t);

				}
				
				list.clear();

			}
			
			return returnList;
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}

	public <T> T queryForObject(String sqlName, Object param, T resultType) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != param){
			
			Object o = this.getSqlMapClient().queryForObject(sqlName,param);

			if(null != o){
				
				return (T)o;

			}else{
				
				return null;

			}
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);

		}
	}
	
	public <T> List<T> queryForListPage(String sqlName,String countSql,PageList pageList,T resultTye) throws SQLException, IgdException {
		
		if(StringUtils.isNotEmpty(sqlName) && null != pageList && null != resultTye){
			
			/**查询数据总条数,默认为无数据*/
			String countStr = "0";
			
			countStr = this.queryForObject(countSql,pageList.getParam(),new String());
			
			if(StringUtils.isNotEmpty(countStr)){
				
				int totalCount = Integer.parseInt(countStr);
				
				int pageNum = totalCount % pageList.getPageSize();
				
				/**根据每页显示条数与总数据量计算可分多少页*/
				if(pageNum == 0){
					
					pageList.setPageNum(totalCount / pageList.getPageSize());
					
				}else{
					
					pageList.setPageNum((totalCount / pageList.getPageSize()) + 1);

				}
				
				/**如果未传入当前页的话则默认设置为第一页*/
				if(pageList.getCurPage() == 0){
					
					pageList.setCurPage(1);

				}
				
				/**设置数据总数*/
				pageList.setDataNum(totalCount);
				
				String startIndex = String.valueOf((pageList.getCurPage() - 1) * pageList.getPageSize());
				
				String endIndex = String.valueOf(pageList.getCurPage() * pageList.getPageSize());
				
				if(StringUtils.isNotBlank(startIndex) && StringUtils.isNotEmpty(endIndex)){
					
					Map<String,String> param = pageList.getParam();
					
					param.put("startNum",startIndex);
					
					param.put("endNum",endIndex);
					
					return this.queryForList(sqlName, param, resultTye);

				}
				
			}
			
		}else{
			
			throw new IgdException(EMPTY_STATMENT_OR_PARAM);
			
		}
		
		return null;
	}
}
